package com.coincalf.web;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.coincalf.dto.UserDTOMapper;
import com.coincalf.dto.UserDetailsMapper;
import com.coincalf.entity.User;
import com.coincalf.entity.UserAuthAuditRecord;
import com.coincalf.enums.AuthStatus;
import com.coincalf.framework.enums.ResultCode;
import com.coincalf.framework.exception.GlobalDefaultException;
import com.coincalf.framework.geetest.GeetestLib;
import com.coincalf.framework.http.Response;
import com.coincalf.framework.security.UserDetails;
import com.coincalf.framework.utils.TokenUtil;
import com.coincalf.service.UserAuthAuditRecordService;
import com.coincalf.service.UserDetailsService;
import com.coincalf.service.UserService;
import com.coincalf.user.dto.UserDTO;
import com.coincalf.web.vo.*;
import com.google.common.base.Strings;
import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;

/**
 * 用户Controller
 *
 * @author qiang
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Api(value = "用户Controller", description = "用户Controller")
public class UserController {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private GeetestLib geetestLib;
    @Autowired
    private UserService userService;
    @Autowired
    private UserAuthAuditRecordService userAuthAuditRecordService;
    @Autowired
    private CommonController commonController;

    @Value(("${google.auth.issuer}"))
    private String issuer;

    /**
     * 获取用户信息
     *
     * @param userDetails
     * @return
     */
    //@GetMapping(value = "/info")
    //@ApiOperation(value = "用户信息", httpMethod = "GET", authorizations = {@Authorization(value = "Authorization")})
    //@PreAuthorize("isAuthenticated()")
    //public Object info(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    User user = userService.selectById(userDetails.getId());
    //    UserDetails u = UserDetailsMapper.INSTANCE.toUserDetails(user);
//
    //    //判断用户高级认证审核状态
    //    EntityWrapper<UserAuthAuditRecord> e1 = new EntityWrapper<>();
    //    e1.eq("user_id", userDetails.getId());
    //    e1.orderBy("created", false);
    //    e1.last(" limit 1");
    //    UserAuthAuditRecord record = userAuthAuditRecordService.selectOne(e1);
    //    Integer seniorAuthStatus = AuthStatus.NOTAUTH.getValue();//未上传图片
    //    if (Optional.ofNullable(record).isPresent()) {
    //        seniorAuthStatus = record.getStatus();
    //    }
    //    u.setSeniorAuthStatus(seniorAuthStatus);
    //    return Response.ok(u);
    //}

    /**
     * 国际化语言切换
     *
     * @param request
     * @param response
     * @param lang
     * @return
     */
    @GetMapping("/lang/{lang}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lang", value = "语言-zh en", dataType = "String", paramType = "query")
    })
    @ApiOperation(value = "切换语言", httpMethod = "GET")
    Object lang(HttpServletRequest request, HttpServletResponse response, @PathVariable String lang) {
        LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);

        if ("zh".equals(lang)) {
            localeResolver.setLocale(request, response, new Locale("zh", "CN"));
        } else if ("en".equals(lang)) {
            localeResolver.setLocale(request, response, new Locale("en", "US"));
        }
        return Response.ok();
    }

    /**
     * 注册接口 暂时废弃 调用PHP那边注册接口...
     *
     * @return
     */
    /*@PostMapping("/register")
    @ApiOperation(value = "首页注册信息", notes = "首页注册信息", httpMethod = "POST")
    public Object register(@ApiParam(value = "注册信息", required = true) @RequestBody @Valid RegisterForm form) {
        String ip = IpUtil.getIpAddr(request);
        // 自定义参数,可选择添加
        HashMap<String, String> param = new HashMap<>();
        param.put("user_id", "qiang"); //网站用户id
        param.put("client_type", "web"); //web:电脑上的浏览器；h5:手机上的浏览器，包括移动应用内完全内置的web_view；native：通过原生SDK植入APP应用的方式
        param.put("ip_address", ip); //传输用户请求验证时所携带的IP
        int gtResult = geetestLib.enhencedValidateRequest(form.getGeetest_challenge(), form.getGeetest_validate(), form.getGeetest_seccode(), param);
        //if (gtResult == 1) {
        if (true) {
            return userService.register(form);
        } else {
            // 验证失败
            throw new GlobalDefaultException(40011);
        }
    }*/

    /**
     * 校验手机号是否已被注册
     *
     * @param mobile
     * @return
     */
    //@GetMapping("/checkTel")
    //@ApiOperation(value = "手机号注册校验", notes = "手机号注册校验", httpMethod = "GET")
    //@ApiImplicitParams({
    //        @ApiImplicitParam(name = "mobile", value = "用户手机号", required = true, dataType = "String", paramType = "query"),
    //        @ApiImplicitParam(name = "countryCode", value = "区号", required = true, dataType = "String", paramType = "query")
    //})

    //public Object checkTel(String mobile, String countryCode) {
    //    if (StringUtils.isEmpty(mobile)) {
    //        throw new GlobalDefaultException(2005);
    //    }
    //    EntityWrapper<User> ew = new EntityWrapper<>();
    //    ew.eq("mobile", mobile);
    //    ew.eq("country_code", countryCode);
    //    int count = userService.selectCount(ew);
    //    if (count > 0) {
    //        throw new GlobalDefaultException(40002);
    //    }
    //    return Response.ok();
    //}

    /**
     * 校验用户名是否已被注册
     *
     * @param username
     * @return
     */
    //@GetMapping("/checkUname")
    //@ApiOperation(value = "用户名注册校验", notes = "用户名注册校验", httpMethod = "GET")
    //@ApiImplicitParams({
    //        @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query")
    //})
    //public Object checkUname(String username) {
    //    if (StringUtils.isEmpty(username)) {
    //        throw new GlobalDefaultException(41041);
    //    }
    //    EntityWrapper<User> ew = new EntityWrapper<>();
    //    ew.eq("username", username);
    //    int count = userService.selectCount(ew);
    //    if (count > 0) {
    //        throw new GlobalDefaultException(40008);
    //    }
    //    return Response.ok();
    //}

    /**
     * 校验邮箱是否已被注册
     *
     * @param email
     * @return
     */
    //@GetMapping("/checkEmail")
    //@ApiOperation(value = "邮箱注册校验", notes = "邮箱注册校验", httpMethod = "GET")
    //@ApiImplicitParams({@ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "String", paramType = "query")})
    //public Object checkEmail(String email) {
    //    if (StringUtils.isEmpty(email)) {
    //        throw new GlobalDefaultException(41042);
    //    }
    //    EntityWrapper<User> ew = new EntityWrapper<>();
    //    ew.eq("email", email);
    //    int count = userService.selectCount(ew);
    //    if (count > 0) {
    //        throw new GlobalDefaultException(40010);
    //    }
    //    return Response.ok();
    //}

    /**
     * 设置支付密码
     *
     * @param changePayPasswordForm
     * @return
     */
    @PostMapping("/setPayPassword")
    @ApiOperation(value = "设置资金密码", notes = "设置资金密码", httpMethod = "POST")
    public Object setPayPassword(HttpServletRequest request, @RequestBody @Valid ChangePayPasswordForm changePayPasswordForm) {
        User user = commonController.getUser(request);
        return userService.setPayPassword(user, changePayPasswordForm);
    }

    /**
     * 修改支付密码
     *
     * @param form
     * @return
     */
    @PostMapping(value = "/updatePayPassword")
    @ApiOperation(value = "ACCOUNT-006 修改资金密码", notes = "修改资金密码", httpMethod = "POST")
    public Object updatePayPassword(HttpServletRequest request, @RequestBody @Valid ChangePasswordForm form) {
        User user = commonController.getUser(request);
        return userService.updatePayPassword(user, form);
    }

    /**
     * 设置用户基本信息
     *
     * @param userDetails
     * @param form
     * @return
     */
    //@PostMapping(value = "/userBase")
    //@ApiOperation(value = "设置用户基础信息", notes = "设置用户基础信息", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object userBase(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails, @RequestBody @Valid UserBaseForm form) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    return userService.setUserBase(userDetails, form);
    //}

    /**
     * 修改手机号
     *
     * @param userDetails
     * @param form
     * @return
     */
    //@PostMapping(value = "/updatePhone")
    //@ApiOperation(value = "ACCOUNT-003 修改手机号", notes = "修改手机号", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object updatePhone(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails, @RequestBody @Valid ChangePhoneForm form) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    return userService.updatePhone(userDetails, form);
    //}

    /**
     * 修改登录密码
     *
     * @param userDetails
     * @param form
     * @return
     */
    //@PostMapping(value = "/updateLoginPassword")
    //@ApiOperation(value = "ACCOUNT-004 修改登录密码", notes = "修改登录密码", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object updatePassword(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails, @RequestBody @Valid ChangePasswordForm form) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    return userService.updatePassword(userDetails, form);
    //}

    /**
     * 查询邀请列表
     *
     * @param userDetails
     * @return
     */
    //@GetMapping(value = "/invitation")
    //@ApiOperation(value = "ACCOUNT-005 邀请列表", notes = "邀请列表", httpMethod = "GET", authorizations = {@Authorization(value = "Authorization")})
    //public Object invitation(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    List<User> userList = userService.selectListByInviteId(userDetails.getId());
    //    return Response.ok(userList);
    //}

    /**
     * 实名认证
     *
     * @param userDetails
     * @param form
     * @return
     */
    //@PostMapping(value = "/authAccount")
    //@ApiOperation(value = "ACCOUNT-007 实名认证", notes = "实名认证", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object authAccount(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails, @RequestBody @Valid UserAuthInfoForm form) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    return userService.updateAuthAccount(userDetails, form);
    //}

    /**
     * 设置密码
     *
     * @param form
     * @return
     */
    //@PostMapping(value = "/setPassword")
    //@ApiOperation(value = "忘记密码", notes = "忘记密码", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object setPassword(@RequestBody @Valid SetPasswordForm form) {
    //    return userService.setPassword(form);
    //}

    /**
     * 高级实名认证
     *
     * @param userDetails
     * @return
     */
    //@PostMapping(value = "/authUser")
    //@ApiOperation(value = "高级认证", notes = "高级认证", httpMethod = "POST", authorizations = {@Authorization(value = "Authorization")})
    //public Object AuthUser(@ApiIgnore @AuthenticationPrincipal UserDetails userDetails, @RequestBody List<String> list) {
    //    if (!Optional.ofNullable(userDetails).isPresent()) {
    //        throw new GlobalDefaultException(1000);
    //    }
    //    if (list.isEmpty()) {
    //        throw new GlobalDefaultException(20010);
    //    }
    //    return userService.authUser(userDetails, list);
    //}

    /**
     * 根据ID查询用户信息（微服务）
     *
     * @param userId
     * @return
     */
    @ApiIgnore
    @PostMapping("/selectById")
    public UserDTO selectById(@RequestParam("userId") Long userId) {
        return UserDTOMapper.INSTANCE.from(userService.selectById(userId));
    }

    /**
     * 根据ID查询用户信息（微服务）
     *
     * @param userName 用户名
     * @return
     */
    //@ApiIgnore
    //@GetMapping("/admin")
    //public UserDTO queryAdminUser(@RequestParam("userName") String userName) {
    //    return UserDTOMapper.INSTANCE.from(userService.queryAdminUser(userName));
    //}

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     */
    //@ApiIgnore
    //@PostMapping("/loadUserByUsername")
    //public Object loadUserByUsername(@RequestParam("userName") String username) {
    //    return userDetailsService.loadUserByUsername(username);
    //}

    /**
     * GA秘钥生成
     *
     * @return
     */
    //@PreAuthorize("isAuthenticated()")
    @GetMapping("/ga/generate")
    @ApiOperation(value = "GA秘钥生成", httpMethod = "GET")
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "请求成功", response = Response.class)
    })
    public Object googleAuthenticatorGenerate(HttpServletRequest request) {
        Long userId = commonController.getUserId(request);
        JSONObject result = new JSONObject();
        GoogleAuthenticator gAuth = new GoogleAuthenticator();
        final GoogleAuthenticatorKey key = gAuth.createCredentials();
        String otpAuthTotpURL = GoogleAuthenticatorQRGenerator.getOtpAuthTotpURL(issuer, String.valueOf(userId), key);
        result.put("otpAuthTotpURL", otpAuthTotpURL);
        result.put("secret_key", key.getKey());
        return Response.ok(result);
    }

    /**
     * GA验证并绑定
     *
     * @param form
     * @return
     */
    //@PreAuthorize("isAuthenticated()")
    @PostMapping("/ga/verify")
    @ApiOperation(value = "GA验证并绑定", httpMethod = "POST")
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "请求成功", response = Response.class),
            @ApiResponse(code = 40004, message = "谷歌验证码错误，请重新输入", response = Response.class)
    })
    public Object googleAuthenticatorVerify(HttpServletRequest request, @RequestBody @Valid GoogleAuthenticatorVerifyForm form, BindingResult result) {
        User user = commonController.getUser(request);
        if (user.getGaStatus().equals(0) || user.getGaStatus() == null) {
            GoogleAuthenticator gAuth = new GoogleAuthenticator();
            if (gAuth.authorize(form.getSecret(), form.getCode())) {
                User userVo = new User();
                userVo.setId(user.getId());
                userVo.setGaSecret(form.getSecret());
                userVo.setGaStatus(1);
                userService.updateById(userVo);
                return Response.ok();
            } else {
                //谷歌验证码错误，请重新输入
                throw new GlobalDefaultException(40004);
            }
        } else {
            //您已开启二次动态口令验证
            throw new GlobalDefaultException(40015);
        }
    }

    @GetMapping("/apikey")
    public Object apikey(HttpServletRequest request) {
        Long userId = commonController.getUserId(request);
        User user = userService.selectById(userId);
        return Response.ok(user);
    }

    @PostMapping("/apikey/get")
    public Object getApikey(HttpServletRequest request) {
        Long userId = commonController.getUserId(request);
        User user = userService.selectById(userId);
        if (Strings.isNullOrEmpty(user.getAccessKeyId())) {
            User userVo = new User();
            userVo.setId(userId);
            String accessKeyId = RandomStringUtils.random(16, true, true);
            String accessKeySecret = RandomStringUtils.random(30, true, true);
            userVo.setAccessKeyId(accessKeyId);
            userVo.setAccessKeySecret(accessKeySecret);
            userService.updateById(userVo);
            return Response.ok(userVo);
        } else {
            //已开启API访问权限
            throw new GlobalDefaultException(42001);
        }
    }

    /**
     * JAVA这边注册接口暂时废弃 调用PHP注册接口 同时PHP调用该接口 将用户数据写入
     *
     * @return
     */
    //@PostMapping("register")
    //@ApiOperation(value = "注册-PHP专用", httpMethod = "POST")
    //public Object register(String token) {
    //    if (StringUtils.isBlank(token)) {
    //        return Response.err(500, "TOKEN不能为空");
    //    }
    //    return userService.registerForPhp(token);
    //}
    public static void main(String[] args) {
        //{"phoneCode":86,"userId":1,"iat":1611387354,"username":"15989001760"}
        Map<String, Object> map = new HashMap<>();
        map.put("phoneCode", 86);
        map.put("userId", 1);
        map.put("iat", 1611387354);
        map.put("username", 123456);
        String token = TokenUtil.createToken(map);
        System.out.println(token);
    }

}
